Skip to content

feat: Add client validation for structuredContent #302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

pantanurag555
Copy link
Contributor

@pantanurag555 pantanurag555 commented Jun 9, 2025

Motivation and Context

This PR adds client-side validation for CallToolResult.structuredContent. The specification was introduced in modelcontextprotocol/modelcontextprotocol@03dc24b.
Resolves #285

Changes in this PR:

  • Add a client-side cache that maintains track of all server tools and their output schemas (if any).
  • Implement a mechanism to refresh the client side cache when encountering a tool call request for an uncached tool.
  • Implement client-side json validation between tool's output schema and result's structured content, when an output schema is specified for tool.
  • Added a new test file that mocks incoming message from transport. Required since Java SDK server implementation already has relevant validations and would be unable to send invalid responses to the client.

How Has This Been Tested?

  • Added tests for success and failure of client-side json validation

Breaking Changes

None

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

mcp/pom.xml Outdated
Comment on lines 205 to 217
<!-- Json validator dependency -->
<dependency>
<groupId>com.networknt</groupId>
<artifactId>json-schema-validator</artifactId>
<version>1.5.7</version>
</dependency>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth getting extra clarification from maintainers on if we want schema validation as part of this or a separate effort, along the lines of the discussion in #271.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed some of the issues offline with @LucaButBoring. I wanted to get clarity around the scope of the work on the issue that I had created. There are a few questions that we might want to answer regarding the output validation:

  1. Do we want validation to be part of this PR or do we want to separate it out and think more about how we can cache/validate the results?
  2. Should cache be in the client class or should we construct a separate cache class?
  3. Should there be refresh intervals for cache invalidation? How else can we deal with it and should it be configurable by the client?
  4. Is a Map the best way to represent cache or should we opt for an in-memory cache implementation like Guava Cache?

Would like inputs from the maintainers to decide on the best way to proceed.

Comment on lines 274 to 261
catch (JsonProcessingException e) {
// Log error if output schema can't be parsed to prevent erroring out for
// successful call tool request
logger.error("Encountered exception when parsing outputSchema: {}", e);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth getting other opinions on this, I think this should be rethrown (potentially wrapped in McpError to keep it unchecked).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. For now, changing this to log a warning. This leaves the option open for the client side implementation to proceed as it deems fit. I would like feedback from others about what would be the ideal behavior in this scenario.

@LucaButBoring
Copy link
Contributor

Just gave this a preliminary review by request, review done for now.

@pantanurag555
Copy link
Contributor Author

Addressed all comments from @LucaButBoring barring a few that where I would like a discussion with maintainers/others from the community.

@tzolov tzolov self-assigned this Jun 26, 2025
@@ -215,7 +244,54 @@ public Object ping() {
* Boolean indicating if the execution failed (true) or succeeded (false/absent)
*/
public McpSchema.CallToolResult callTool(McpSchema.CallToolRequest callToolRequest) {
return this.delegate.callTool(callToolRequest).block();
McpSchema.CallToolResult result = this.delegate.callTool(callToolRequest).block();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Shift to sync instead.

@tzolov tzolov mentioned this pull request Jul 22, 2025
@pantanurag555 pantanurag555 changed the title feat: Add Tool.outputSchema and CallToolResult.structuredContent feat: Add client validation for structuredContent Jul 22, 2025
@pantanurag555
Copy link
Contributor Author

pantanurag555 commented Jul 22, 2025

Updated the PR to leverage the existing json validator and to perform only client-side validations. Added a new test file to mock transport for the sync client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add OutputSchema to Tool and CallToolResult.structuredContent
3 participants